package GUI;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Hashtable;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.border.SoftBevelBorder;
import javax.swing.border.TitledBorder;

import Simulator.Simulator;

public class GUI implements ActionListener {
	private JFrame main;
	private JButton start, reset, rabbit, fox, bird;
	private JPanel topMenu, simulationPane, settingsPane;
	private Container contentPane;
	private JMenuItem quit;
	private JSlider steps, speed;
	private static Simulator simulator;
	private SettingsPane rabbitSettings, foxSettings, birdSettings, legendView;
	// Variable that tells if the program is running
	private boolean running = false;
	Thread sim;

	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {

		}
		new GUI();
	}

	public GUI() {
		makeFrame();
		makeTopMenu();
		main.pack();
		main.setVisible(true);
		setSimulator();
		makeLegendView();
	}

	public void makeFrame() {
		main = new JFrame("Foxes and Rabbits");
		main.setPreferredSize(new Dimension(1000, 125));
		main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		contentPane = main.getContentPane();
		contentPane.setBackground(Color.white);
	}

	public void makeTopMenu() {
		topMenu = new JPanel();
		topMenu.setPreferredSize(new Dimension(1000, 100));
		topMenu.setLayout(new GridLayout(1, 4));
		topMenu.setBorder(new SoftBevelBorder(1));
		Hashtable<Integer, JLabel> stepsTable = new Hashtable<Integer, JLabel>();
		stepsTable.put(0, new JLabel("0"));
		stepsTable.put(250, new JLabel("250"));
		stepsTable.put(500, new JLabel("500"));
		Hashtable<Integer, JLabel> speedTable = new Hashtable<Integer, JLabel>();
		speedTable.put(0, new JLabel("0"));
		speedTable.put(500, new JLabel("500"));
		speedTable.put(1000, new JLabel("1000"));
		steps = new JSlider(0, 500, 50);
		steps.setBorder(new TitledBorder("Number of steps"));
		steps.setLabelTable(stepsTable);
		steps.setPaintLabels(true);
		steps.setToolTipText("Number of steps.");
		speed = new JSlider(0, 1000, 500);
		speed.setBorder(new TitledBorder("Speed"));
		speed.setLabelTable(speedTable);
		speed.setPaintLabels(true);
		speed.setToolTipText("Speed of the simulation.");
		simulationPane = new JPanel();
		simulationPane.setPreferredSize(new Dimension(100, 150));
		simulationPane.setBorder(new TitledBorder("Simulation"));
		simulationPane.setLayout(new GridLayout(1, 0, 2, 10));
		start = new JButton("Start");
		start.addActionListener(this);
		reset = new JButton("Reset");
		reset.addActionListener(this);
		simulationPane.add(start);
		simulationPane.add(reset);
		settingsPane = new JPanel();
		settingsPane.setPreferredSize(new Dimension(100, 200));
		settingsPane.setBorder(new TitledBorder("Settings"));
		settingsPane.setLayout(new GridLayout(1, 0, 2, 10));
		rabbit = new JButton("Rabbit");
		rabbit.addActionListener(this);
		fox = new JButton("Fox");
		fox.addActionListener(this);
		bird = new JButton("Bird");
		bird.addActionListener(this);
		settingsPane.add(rabbit);
		settingsPane.add(fox);
		settingsPane.add(bird);
		topMenu.add(steps);
		topMenu.add(speed);
		topMenu.add(simulationPane);
		topMenu.add(settingsPane);
		contentPane.add(topMenu, BorderLayout.NORTH);
	}

	public void setSimulator() {
		simulator = new Simulator(50, 50);
	}

	public static Simulator getSimulator() {
		return simulator;
	}

	public void makeLegendView() {
		legendView = new SettingsPane();
		legendView.makeLegend();
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == quit) {
			System.exit(1);
		} else if (e.getSource() == start) {
			if (!getRunning()) {
				setRunning(true);
				sim = new Thread(new SimulateSteps());
				sim.start();
			}
		} else if (e.getSource() == reset) {
			if (!getRunning()) {
				simulator.reset();
			}
		} else if (e.getSource() == rabbit) {
			if (rabbitSettings == null) {
				rabbitSettings = new SettingsPane();
				rabbitSettings.setRabbitsPane();
			} else {
				rabbitSettings.setVisible(true);
			}
		} else if (e.getSource() == fox) {
			if (foxSettings == null) {
				foxSettings = new SettingsPane();
				foxSettings.setFoxPane();
			} else {
				foxSettings.setVisible(true);
			}
		} else if (e.getSource() == bird) {
			if (birdSettings == null) {
				birdSettings = new SettingsPane();
				birdSettings.setBirdPane();
			} else {
				birdSettings.setVisible(true);
			}
		}
	}

	class SimulateSteps implements Runnable {
		public void run() {
			simulator.simulate(steps.getValue(), (1000 - speed.getValue()));
			setRunning(false);
		}
	}

	private boolean getRunning() {
		return running;
	}

	private void setRunning(boolean running) {
		this.running = running;
	}
}
